import { App, createApp, Plugin, reactive, ref } from 'vue';
import AppVue from '../App.vue';
import { Component, Directive } from '@vue/runtime-core';
import { RouteLocationNormalized, Router, RouteRecordRaw } from 'vue-router';
import { setupRouter } from '@/router';
import { setupStore } from '@/store';
import { setupDirectives } from '@/plugins';
import { config } from '@/MyLayerConfig';
import SlashLayer from 'slash-layer';
import naive from 'naive-ui';
import Timeout = NodeJS.Timeout;
import { CurrentUser } from '..';
import { allStore } from '@/store/all';
import { setLayerTheme } from '@/utils/theme';
import MyUpload from './test-button.vue'
import Login from '@/views/login/Login.vue';

export declare type SlashAppInstallFunction = (
  slashAppContext: SlashAppContext,
  ...options: any[]
) => any;

export declare interface SlashApp {
  install: SlashAppInstallFunction;
}

export declare interface AppConfig {
  //http请求基础路径
  httpBaseUrl: string;
  //文件上传预览基础路径
  fileBaseUrl: string;
  //文件上传路径
  fileUploadUri: string;
  loginSuccessRouterPath: string;
  loginSuccessRouterTitle: string;
  loginPath: string;
  loginSuccessInnerOpen: boolean;
}

export declare interface AppContext {
  fromPath?: RouteLocationNormalized | null;
  isRouteReady: boolean;
  routeReadyCallBack?: (result: boolean) => void;
  awaitRoutePath: string;
}

export declare interface GlobalApplicationConfigurationType {
  logoName: string;
  profile: string;
  logoImg: string;
  loginComponent?: Component;
  headerComponents?: Component[];
}

export const GlobalApplicationConfiguration = reactive<GlobalApplicationConfigurationType>({
  loginComponent: undefined,
  logoName: '后台管理系统',
  profile: 'prod',
  logoImg: '',
  headerComponents:[ MyUpload]
});
export const appConfig = ref<AppConfig>(
  reactive({
    //http请求基础路径
    httpBaseUrl: '',
    //文件上传预览基础路径
    fileBaseUrl: '',
    fileUploadUri:
      window.sessionStorage.getItem('fileUploadUri') || '/resourceApp/resource/uploadFile',
    loginSuccessRouterPath: '/navigation/welcome',
    loginSuccessRouterTitle: '欢迎页',
    loginSuccessInnerOpen: true,
    loginPath: '/login',
  })
);
export const currentUser = ref<CurrentUser>({
  account: '',
  admin: false,
  deptCode: '',
  headImgAddress: '',
  nickName: '',
  userId: '',
  username: '',
  roleCodes: [],
});
export const avatarOptions = ref([
  {
    label: '修改密码',
    key: 'updatePassword',
  },
  {
    label: '退出登录',
    key: 'loginOut',
  },
]);
export const appContext = ref<AppContext>(
  reactive<AppContext>({
    isRouteReady: false,
    fromPath: null,
  })
);
export default class SlashAppContext {
  public static _app: App;
  public static _appId: string;

  static isRouterReady(path: string): Promise<boolean> {
    appContext.value.awaitRoutePath = path;
    return new Promise(function (resolve, reject) {
      const timer: Timeout = setTimeout(function () {
        resolve(appContext.value.isRouteReady);
      }, 3000);
      appContext.value.routeReadyCallBack = resolve;
      if (appContext.value.isRouteReady) {
        clearTimeout(timer);
        resolve(true);
      }
    });
  }

  static async routerReady() {
    appContext.value.isRouteReady = true;
    if (appContext.value.routeReadyCallBack) {
      appContext.value.routeReadyCallBack(true);
      appContext.value.routeReadyCallBack = undefined;
    }
  }

  static async init() {
    if (!SlashAppContext._app) {
      console.error('请先创建应用');
      return;
    }
    await SlashAppContext.use(naive);
    await setupStore(SlashAppContext._app);
    await setupRouter(SlashAppContext._app);
    SlashAppContext._app.config.warnHandler = () => null;
    await setupDirectives(SlashAppContext._app);
    await SlashAppContext.use(SlashLayer, config);
    console.log('应用初始化完成');
  }

  public static getBaseUrl() {
    return appConfig.value.httpBaseUrl;
  }

  public static fileBaseUrl() {
    return appConfig.value.fileBaseUrl;
  }

  public static getFileUploadUrl() {
    return appConfig.value.fileBaseUrl + appConfig.value.fileUploadUri;
  }

  public static setAppConfig(config: AppConfig) {
    appConfig.value = reactive(config);
  }

  public static getAppConfig() {
    return appConfig.value;
  }

  public static setFromPath(fromPath: RouteLocationNormalized) {
    appContext.value.fromPath = fromPath;
  }

  public static getGlobalApplicationConfiguration() {
    return GlobalApplicationConfiguration;
  }

  public static getAvatarOptions() {
    return avatarOptions;
  }

  public static addAvatarOptions(option: any, index: number) {
    console.log(index);
    avatarOptions.value.push(option);
  }

  public static setCurrentUser(user: CurrentUser) {
    currentUser.value = user;
  }

  public static getCurrentUser() {
    return currentUser;
  }

  public static doAvatarOptionsMethod(key: any) {
    for (let i = 0; i < avatarOptions.value.length; i++) {
      if (avatarOptions.value[i].key == key) {
        if (typeof avatarOptions.value[i] != 'undefined') {
          // @ts-ignore
          avatarOptions.value[i].onSelect();
        }
      }
    }
  }

  public static back() {
    const fromPath = appContext.value.fromPath;
    if (fromPath) {
      SlashAppContext.getRouter()?.push({
        path: fromPath.path,
        query: {
          ...fromPath.query,
        },
      });
    }
  }

  static getRouter(): Router | null {
    if (SlashAppContext._app) {
      const router: Router = SlashAppContext._app.config.globalProperties.$router;
      if (router == null) {
      }
      return SlashAppContext._app.config.globalProperties.$router;
    }
    return null;
  }

  static getAppStore() {
    return allStore;
  }

  static async addRouters(routeArray: RouteRecordRaw[]) {
    for (const routeArrayKey of routeArray) {
      console.log(SlashAppContext.getRouter());
      if (routeArrayKey.path == appContext.value.awaitRoutePath) {
        await SlashAppContext.routerReady();
      }
      console.log('注册路由:{}', routeArrayKey);
      SlashAppContext.getRouter()?.addRoute(routeArrayKey);
    }
  }

  static setLogoName(logName: string): void {
    GlobalApplicationConfiguration.logoName = logName;
  }

  static async mount(id: string, isHydrate: boolean) {
    await SlashAppContext.getRouter()?.isReady();
    if (!SlashAppContext._appId && SlashAppContext._app) {
      SlashAppContext._appId = id;
      SlashAppContext._app.mount(SlashAppContext._appId, isHydrate);
      console.log('挂载成功:', SlashAppContext._appId);
    } else {
      console.log('挂载失败');
    }
  }

  static async use(plugin: Plugin, options?: any) {
    if (plugin) {
      console.log('加载子系统', plugin);
      SlashAppContext._app.use(plugin, options);
    }
  }

  static async createApp(component: Component | null) {
    console.log('创建应用');
    if (typeof SlashAppContext._app === 'undefined') {
      if (component) {
        const app = createApp(component);
        SlashAppContext._app = app;
      } else {
        const app = createApp(AppVue);
        SlashAppContext._app = app;
      }
      console.log('创建App成功');
    } else {
      console.error('创建App失败');
    }
  }

  static async directive(key: string, value: Directive) {
    // @ts-ignore
    SlashAppContext._app.directive(key, value);
  }

  static async useSlashApp(slashApp: SlashApp, option: any) {
    slashApp.install(SlashAppContext, option);
  }

  static setLayerTheme(val: 'header-dark' | 'dark') {
    return setLayerTheme(val);
  }

  static getRequest(): any {
    const url = location.href; //获取url中'?'符后的字串
    const theRequest = new Object();
    const index = url.indexOf('?');
    if (index != -1) {
      const str = url.substr(index + 1);
      const stars = str.split('&');
      for (let i = 0; i < stars.length; i++) {
        // @ts-ignore
        theRequest[stars[i].split('=')[0]] = decodeURI(stars[i].split('=')[1]);
      }
    }
    return theRequest;
  }
}
